package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.BaseException;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.SetmealService;
import com.sky.vo.DishItemVO;
import com.sky.vo.DishVO;
import com.sky.vo.SetmealVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    /**
     * 新增套餐
     * @param setmealDTO
     */
    //@Cacheable(cacheNames = "setmeal:cache",key = "#setmealDTO.categoryId")
    @Override
    public void save(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO,setmeal);
        // 1.保存套餐基本信息
        setmeal.setStatus(StatusConstant.DISABLE);
        setmealMapper.insert(setmeal);

        // 2.保存套餐内菜品信息
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();

        setmealDishes.forEach(setmealDishe -> {
            setmealDishe.setSetmealId(setmeal.getId());
        });
        setmealDishMapper.insertBatch(setmealDishes);
    }


    /**
     * 分页查询
     * @param setmealPageQueryDTO
     * @return
     */
    @Override
    public PageResult page(SetmealPageQueryDTO setmealPageQueryDTO) {
        // 1.设置分页参数
        PageHelper.startPage(setmealPageQueryDTO.getPage(), setmealPageQueryDTO.getPageSize());

        // 2.执行查询
        List<SetmealVO> setmealVOList = setmealMapper.pageQuery(setmealPageQueryDTO);

        // 3.解析并封装分页结果
        Page<SetmealVO> page = (Page<SetmealVO>) setmealVOList;

        return new PageResult(page.getTotal(),page.getResult());

    }

    /**
     * 修改套餐
     * @param setmealDTO
     */
    @Transactional
    @CacheEvict(cacheNames = "setmeal:cache" , allEntries = true)
    @Override
    public void update(SetmealDTO setmealDTO) {
        // 1.根据Id修改套餐的基本信息 -- setmeal
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO,setmeal);
        setmealMapper.update(setmeal);

        // 2.根据套餐id修改套餐菜品信息 -- setmeal_dish (先删 后加)
        // 2.1 根据套餐id删除菜品数据
        setmealDishMapper.deleteSetmealDishBySetmealIds(Collections.singletonList(setmeal.getId()));

        // 2.2 在添加
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();

        setmealDishes.forEach(setmealDishe -> {
            setmealDishe.setSetmealId(setmeal.getId());
        });
        setmealDishMapper.insertBatch(setmealDishes);
    }

    /**
     * 根据ID查询，用于页面回显
     * @param id
     * @return
     */
    @Override
    public SetmealVO getInfo(Long id) {
        // 1.根据Id查询套餐的基本信息 - Setmeal
        Setmeal setmeal = setmealMapper.getById(id);


        // 2.根据Id查询套餐的菜品列表信息 - List<SetmealDish>
        List<SetmealDish> setmealDishList = setmealDishMapper.getBySetmealId(id);

        // 3.组装数据
        SetmealVO setmealVO = new SetmealVO();
        if (!(setmeal == null)){
            BeanUtils.copyProperties(setmeal,setmealVO);
        }
        setmealVO.setSetmealDishes(setmealDishList);

        return setmealVO;



    }

    /**
     * 批量删除套餐
     * @param ids
     */
    @Transactional
    @CacheEvict(cacheNames = "setmeal:cache" , allEntries = true)
    @Override
    public void delete(List<Long> ids) {
        // 1.判断套餐的状态，启售的套餐不能删除，提示错误信息
        Long count = setmealMapper.countEnableSetmealByIds(ids);
        if (count > 0){
            throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
        }
        // 2.判断套餐是否关联菜品，如果关联菜品，不能删除，提示错误信息
        List<Long> dishIds =  setmealDishMapper.getDishIdsBySetmealIds(ids);
        if (!CollectionUtils.isEmpty(dishIds)){  // 关联了菜品
            throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
        }

        // 3.删除套餐，并删除套餐菜品
        setmealMapper.deleteByIds(ids);
        // 删除套餐关联的菜品
        setmealDishMapper.deleteSetmealDishBySetmealIds(ids);

    }

    @Cacheable(cacheNames = "setmeal:cache",key = "#a0.categoryId")
    @Override
    public List<SetmealVO> listWithFlavor(Setmeal setmeal) {
        // 根据分类id查询套餐，并且是启用状态的套餐
        List<Setmeal> setmealList = setmealMapper.list(setmeal);

        List<SetmealVO> setmealDishList = new ArrayList<>();
        // 将每一个菜品数据拷贝给setmealVO并且封装每一个套餐里面的菜品数据给setmealVO
        for (Setmeal s : setmealList) {
            SetmealVO setmealVO = new SetmealVO();
            BeanUtils.copyProperties(s,setmealVO);

            //根据套餐id查询对应的菜品
            List<SetmealDish> setmealDishes = setmealDishMapper.getBySetmealId(setmeal.getId());

            setmealVO.setSetmealDishes(setmealDishes);
            setmealDishList.add(setmealVO);
        }

        return setmealDishList;
    }

    /**
     * 根据套餐id查询菜品
     * @param id
     * @return
     */
    @Override
    public List<DishItemVO> listDishItem(Long id) {

        List<DishItemVO> item = setmealDishMapper.getDishItemBySetmealId(id);


        return item;
    }
}
